defmodule FtpManager do
    @moduledoc false

    alias SFTPClient.Config

    @table_name :ftp_connects

    def start do
        :ets.new(@table_name, [:protected, :named_table])
    end

    def start_ftp(ftp_name, host, user, password) do
        with false <- :ets.member(@table_name, ftp_name) do
            config = %Config{
                host: host,
                port: 22,
                user: user,
                password: password
            }

            case SFTPClient.connect(config) do
                {:ok, conn} ->
                    :ets.insert_new(@table_name, {ftp_name, conn})
                    {:ok, conn}

                _ ->
                    {:failed, nil}
            end
        else
            _ -> {:already_started}
        end
    end

    def stop_ftp(ftp_name) do
        case :ets.take(@table_name, ftp_name) do
            [{^ftp_name, conn}] ->
                SFTPClient.disconnect(conn)

            _ ->
                nil
        end

        :ok
    end

    def upload_file(ftp_name, local_path, remote_path) do
        case :ets.lookup(@table_name, ftp_name) do
            [{^ftp_name, conn}] ->
                SFTPClient.upload_file(conn, local_path, remote_path)

            _ ->
                {:failed, :no_connect}
        end
    end

    def download_file(ftp_name, local_path, remote_path) do
        case :ets.lookup(@table_name, ftp_name) do
            [{^ftp_name, conn}] ->
                SFTPClient.download_file(conn, local_path, remote_path)

            _ ->
                {:failed, :no_connect}
        end
    end

    def upload_file(local_path, remote_path) do
        config = %Config{
            host: AppConfigure.fetch("TRI_FTP_HOST"),
            port: 22,
            user: AppConfigure.fetch("TRI_FTP_USER"),
            password: AppConfigure.fetch("TRI_FTP_PASS")
        }

        case SFTPClient.connect(config) do
            {:ok, conn} ->
                case SFTPClient.upload_file(conn, local_path, remote_path) do
                    {:ok, _path} ->
                        SFTPClient.disconnect(conn)
                        :ok

                    _ ->
                        :failed
                end

            _ ->
                :failed
        end
    end

    def download_file(remote_path, local_path) do
        config = %Config{
            host: AppConfigure.fetch("TRI_FTP_HOST"),
            port: 22,
            user: AppConfigure.fetch("TRI_FTP_USER"),
            password: AppConfigure.fetch("TRI_FTP_PASS")
        }

        case SFTPClient.connect(config) do
            {:ok, conn} ->
                case SFTPClient.download_file(conn, remote_path, local_path) do
                    {:ok, _path} ->
                        SFTPClient.disconnect(conn)
                        :ok

                    _ ->
                        :failed
                end

            _ ->
                :failed
        end
    end

end
